package com.quwan.security.user;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.quwan.common.constant.RedisKeyConsts;
import com.quwan.common.enums.MemberStatusEnum;
import com.quwan.common.exception.ExpCode;
import com.quwan.common.exception.ResponseException;
import com.quwan.constans.AppConst;
import com.quwan.entity.TAdmin;
import com.quwan.entity.TMember;
import com.quwan.mapper.TAdminMapper;
import com.quwan.mapper.TMemberMapper;
import com.quwan.utils.redis.Redis;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;

/**
 * @author quan
 * @date 2021-06-06 18:49
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class JwtUserDetailsServiceImpl implements UserDetailsService {
    private final TMemberMapper memberMapper;
    private final TAdminMapper adminMapper;
    private final Redis redis;
    @Value("${jwt.keepLive}")
    private String refreshExpiration;
    private final HttpServletResponse response;

    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
        try {
            String[] userInfo = userName.split("@@");
            String account = userInfo != null && userInfo.length > 0 ? userInfo[0] : "";
            String module = userInfo != null && userInfo.length > 1 ? userInfo[1] : "";
            return loadModuleUserInfo(account, module);
        } catch (Exception e) {
            throw new UsernameNotFoundException(String.format("getUserAuthInfo Exception：%s.", e == null ? "NULL" : e.getMessage()));
        }
    }

    private UserDetails loadModuleUserInfo(String mobile, String module) {
        String redisUserKey = RedisKeyConsts.PLATFORM + mobile;
        Object token = redis.get(redisUserKey);
        //  log.info("最新token:" + token);
        if (token != null) {
            redis.setEx(redisUserKey, token, Long.valueOf(refreshExpiration) * 24 * 3600);
            redis.set(token, redisUserKey, Long.valueOf(refreshExpiration) * 24 * 3600);
        }
        try {
            if (AppConst.MEMBER_MODULE.equalsIgnoreCase(module)) {
                TMember member = memberMapper.selectOne(
                        new LambdaQueryWrapper<TMember>()
                                .select(TMember::getId, TMember::getMobile, TMember::getPassword, TMember::getStatus)
                                .eq(TMember::getMobile, mobile));
                if (member != null) {
                    if (member.getStatus().equals(MemberStatusEnum.DISABLED.getCode()))
                        throw new ResponseException(ExpCode.ACCOUNT_DISABLED.getCode(), ExpCode.ACCOUNT_DISABLED.getMsg());
                    return JwtUserDetails.I(member.getId() + "", member.getMobile() + "", member.getPassword(), module);
                } else {
                    throw new UsernameNotFoundException("member Info notFound");
                }
            } else if (AppConst.ADMIN_MODULE.equalsIgnoreCase(module)) {
                TAdmin admin = adminMapper.selectOne(
                        new LambdaQueryWrapper<TAdmin>()
                                .select(TAdmin::getId, TAdmin::getLoginName, TAdmin::getPassword, TAdmin::getRoleId)
                                .eq(TAdmin::getLoginName, mobile)
                                .eq(TAdmin::getStatus, 0));
                if (admin != null) {
                    return JwtUserDetails.I(admin.getId() + "", admin.getLoginName() + "", admin.getPassword(), module);
                } else {
                    throw new UsernameNotFoundException("admin Info notFound");
                }
            } else {
                throw new UsernameNotFoundException("undefined module:" + module);
            }

        } catch (Exception e) {
            throw new UsernameNotFoundException(String.format("getUserAuthInfo Exception：%s.", e.getMessage()));
        }
    }
}
